/* eslint-disable consistent-return */
/**
 * Copyright (c) 快宝网络 kuaidihelp.com Co., Ltd. All Rights Reserved 禁止外泄以及用于其它的商业用途
 */

import moment from 'moment';
import { parse, stringify } from 'qs';
import { isEmpty, isObject } from 'lodash';
import { loginEncryption } from '@/services/user';
import CryptoJS from 'crypto-js';
import brands from '@kb/brands';

export function fixedZero(val) {
  return val * 1 < 10 ? `0${val}` : val;
}

export function getTimeDistance(type) {
  const now = new Date();
  const oneDay = 1000 * 60 * 60 * 24;

  if (type === 'today') {
    now.setHours(0);
    now.setMinutes(0);
    now.setSeconds(0);
    return [moment(now), moment(now.getTime() + (oneDay - 1000))];
  }

  if (type === 'week') {
    let day = now.getDay();
    now.setHours(0);
    now.setMinutes(0);
    now.setSeconds(0);

    if (day === 0) {
      day = 6;
    } else {
      day -= 1;
    }

    const beginTime = now.getTime() - day * oneDay;

    return [moment(beginTime), moment(beginTime + (7 * oneDay - 1000))];
  }

  if (type === 'month') {
    const year = now.getFullYear();
    const month = now.getMonth();
    const nextDate = moment(now).add(1, 'months');
    const nextYear = nextDate.year();
    const nextMonth = nextDate.month();

    return [
      moment(`${year}-${fixedZero(month + 1)}-01 00:00:00`),
      moment(moment(`${nextYear}-${fixedZero(nextMonth + 1)}-01 00:00:00`).valueOf() - 1000),
    ];
  }

  if (type === 'year') {
    const year = now.getFullYear();

    return [moment(`${year}-01-01 00:00:00`), moment(`${year}-12-31 23:59:59`)];
  }
}

export function getPlainNode(nodeList, parentPath = '') {
  const arr = [];
  nodeList.forEach(node => {
    const item = node;
    item.path = `${parentPath}/${item.path || ''}`.replace(/\/+/g, '/');
    item.exact = true;
    if (item.children && !item.component) {
      arr.push(...getPlainNode(item.children, item.path));
    } else {
      if (item.children && item.component) {
        item.exact = false;
      }
      arr.push(item);
    }
  });
  return arr;
}

function accMul(arg1, arg2) {
  let m = 0;
  const s1 = arg1.toString();
  const s2 = arg2.toString();
  m += s1.split('.').length > 1 ? s1.split('.')[1].length : 0;
  m += s2.split('.').length > 1 ? s2.split('.')[1].length : 0;
  return (Number(s1.replace('.', '')) * Number(s2.replace('.', ''))) / 10 ** m;
}

export function digitUppercase(n) {
  const fraction = ['角', '分'];
  const digit = ['零', '壹', '贰', '叁', '肆', '伍', '陆', '柒', '捌', '玖'];
  const unit = [['元', '万', '亿'], ['', '拾', '佰', '仟', '万']];
  let num = Math.abs(n);
  let s = '';
  fraction.forEach((item, index) => {
    s += (digit[Math.floor(accMul(num, 10 * 10 ** index)) % 10] + item).replace(/零./, '');
  });
  s = s || '整';
  num = Math.floor(num);
  for (let i = 0; i < unit[0].length && num > 0; i += 1) {
    let p = '';
    for (let j = 0; j < unit[1].length && num > 0; j += 1) {
      p = digit[num % 10] + unit[1][j] + p;
      num = Math.floor(num / 10);
    }
    s = p.replace(/(零.)*零$/, '').replace(/^$/, '零') + unit[0][i] + s;
  }

  return s
    .replace(/(零.)*零元/, '元')
    .replace(/(零.)+/g, '零')
    .replace(/^整$/, '零元整');
}

function getRelation(str1, str2) {
  if (str1 === str2) {
    console.warn('Two path are equal!'); // eslint-disable-line
  }
  const arr1 = str1.split('/');
  const arr2 = str2.split('/');
  if (arr2.every((item, index) => item === arr1[index])) {
    return 1;
  }
  if (arr1.every((item, index) => item === arr2[index])) {
    return 2;
  }
  return 3;
}

function getRenderArr(routes) {
  let renderArr = [];
  renderArr.push(routes[0]);
  for (let i = 1; i < routes.length; i += 1) {
    // 去重
    renderArr = renderArr.filter(item => getRelation(item, routes[i]) !== 1);
    // 是否包含
    const isAdd = renderArr.every(item => getRelation(item, routes[i]) === 3);
    if (isAdd) {
      renderArr.push(routes[i]);
    }
  }
  return renderArr;
}

/**
 * Get router routing configuration
 * { path:{name,...param}}=>Array<{name,path ...param}>
 * @param {string} path
 * @param {routerData} routerData
 */
export function getRoutes(path, routerData) {
  let routes = Object.keys(routerData).filter(
    routePath => routePath.indexOf(path) === 0 && routePath !== path,
  );
  // Replace path to '' eg. path='user' /user/name => name
  routes = routes.map(item => item.replace(path, ''));
  // Get the route to be rendered to remove the deep rendering
  const renderArr = getRenderArr(routes);
  // Conversion and stitching parameters
  const renderRoutes = renderArr.map(item => {
    const exact = !routes.some(route => route !== item && getRelation(route, item) === 1);
    return {
      exact,
      ...routerData[`${path}${item}`],
      key: `${path}${item}`,
      path: `${path}${item}`,
    };
  });
  return renderRoutes;
}

export function getPageQuery() {
  return parse(window.location.href.split('?')[1]);
}

export function getQueryPath(path = '', query = {}) {
  const search = stringify(query);
  if (search.length) {
    return `${path}?${search}`;
  }
  return path;
}

/* eslint no-useless-escape:0 */
const reg = /(((^https?:(?:\/\/)?)(?:[-;:&=\+\$,\w]+@)?[A-Za-z0-9.-]+(?::\d+)?|(?:www.|[-;:&=\+\$,\w]+@)[A-Za-z0-9.-]+)((?:\/[\+~%\/.\w-_]*)?\??(?:[-\+=&;%@.\w_]*)#?(?:[\w]*))?)$/;

export function isUrl(path) {
  return reg.test(path);
}

export function dateCalendar(val, showSecond = false) {
  const dateFormat = showSecond ? 'YYYY-MM-DD HH:mm:ss' : 'YYYY-MM-DD HH:mm';
  const language = showSecond ? 'LTS' : 'LT';
  return val
    ? moment(val).calendar(null, {
        lastDay: `[昨天] ${language}`,
        sameDay: `[今天] ${language}`,
        nextDay: `[明天] ${language}`,
        lastWeek: dateFormat,
        nextWeek: dateFormat,
        sameElse: dateFormat,
      })
    : '';
}

export function timeDistance(from, to) {
  const fmoment = moment(from);
  const tmoment = moment(to);
  const ts = Math.abs(fmoment.diff(tmoment));
  const d = parseInt(ts / (1000 * 60 * 60 * 24));
  const h = parseInt((ts % (1000 * 60 * 60 * 24)) / (1000 * 60 * 60), 10);
  const m = parseInt((ts % (1000 * 60 * 60)) / (1000 * 60), 10);
  const s = parseInt((ts % (1000 * 60)) / 1000);
  const times = [];
  d > 0 && times.push(`${d}天`);
  h > 0 && times.push(`${h}小时`);
  m > 0 && times.push(`${m}分钟`);
  if (m <= 0 && s > 0) {
    times.push(`${s}秒`);
  }
  return times.join('');
}

// 全屏
export function switchFullscreen(isScreen, ele) {
  if (isScreen === isFullscreen()) {
    return;
  }
  const doc = ele || document.documentElement;
  if (doc.requestFullscreen) {
    isScreen ? doc.requestFullscreen() : document.exitFullscreen();
  } else if (doc.webkitRequestFullScreen) {
    isScreen ? doc.webkitRequestFullScreen() : document.webkitExitFullscreen();
  } else if (doc.mozRequestFullScreen) {
    isScreen ? doc.mozRequestFullScreen() : document.mozCancelFullScreen();
  } else if (ele) {
    const fclass = ' full-screen';
    if (isScreen) {
      ele.className = ele.className.trim() + fclass;
    } else {
      ele.className = ele.className.replace(fclass, '');
    }
  }
}

function isArray(arr) {
  return arr instanceof Array;
}

function isFullscreen() {
  return document.fullscreen || document.mozFullScreen || document.webkitFullscreen;
}

export { isFullscreen, isArray };

export function removeLStorage(key) {
  try {
    window.localStorage.removeItem(key);
  } catch (e) {}
}

export function setLStorage(key, data) {
  window.localStorage.setItem(key, JSON.stringify({ data }));
}

export function getLStorage(key) {
  const data = window.localStorage.getItem(key);
  try {
    return JSON.parse(data).data;
  } catch (e) {
    return data;
  }
}

/**
 * 首字母大写 [string,boolean]，是否将其他字符小写
 */
export const firstUpperCase = (str, islower) => {
  if (typeof str === 'string') {
    const reg = /\b(\w)|\s(\w)/g;
    str = islower ? str.toLowerCase() : str;
    return str.replace(reg, m => m.toUpperCase());
  }
  return str;
};

/**
 * 数组切割
 * @param {array} array 被切割的数组
 * @param {number} size 每份的数量
 * @returns {array} 返回被切割的数组
 *  */
export const sliceArrByNum = (array, size) => {
  const newArr = [];
  let index = 0;
  const arrayLength = array.length;
  for (let i = 0; i < array.length; i++) {
    const element = array[i];
    if (i % size == 0 && i !== 0) {
      newArr.push(array.slice(index, i));
      index = i;
    }
    if (i + 1 === arrayLength) {
      newArr.push(array.slice(index, i + 1));
    }
  }

  return newArr;
};

/**
 * get方法序列化参数
 */
export const serializeGetData = params => {
  const paramsArray = [];
  Object.keys(params).forEach(key => paramsArray.push(`${key}=${params[key]}`));
  const data = paramsArray.join('&');
  return data;
};
/**
 * 检查数据是否有效，否则返回空数据
 */
export const isLegalData = (data, type = []) => {
  if (data) {
    if (isEmpty(data)) {
      return type;
    }
    return data;
  }
  return type;
};
// Cookie操作
// 保存cookie
// 参数：cookie名,cookie值,有效时长(单位：秒，默认一分钟)
export function saveCookie(cookieName, cookieValue, cookieDates = 60) {
  const d = new Date();
  d.setTime(d.getTime() + cookieDates * 1000);
  document.cookie = `${cookieName}=${cookieValue};expires=${d.toGMTString()}`;
}
// Cookie获取
export function getCookie(cookieName) {
  const cookieStr = unescape(document.cookie);
  const arr = cookieStr.split('; ');
  let cookieValue = '';
  for (let i = 0; i < arr.length; i++) {
    const temp = arr[i].split('=');
    if (temp[0] == cookieName) {
      cookieValue = temp[1];
      break;
    }
  }
  return cookieValue;
}
// 删除cookie
export function removeCookie(cookieName) {
  document.cookie = `${encodeURIComponent(cookieName)}=; expires=${new Date()}`;
}

/**
 * CryptoJS 加密
 * @param {object} object 需要加密的对象
 * @returns {object} 返回被加密的object对象，只加密object的value值
 */
export async function encryption(object = {}) {
  const res = await loginEncryption({ phone: object.phone });
  delete object.phone;
  const { code, data = {}, msg } = res;
  const { token } = data;
  const iv = 'kuaidihelp666666';

  const cryptoKeys = Object.keys(data)
    .filter(i => i !== 'token')
    .sort((a, b) => a.charCodeAt(0) - b.charCodeAt(0));

  const cryptoKey = cryptoKeys.map(i => data[i]).join('');

  const cipher = (value, key) =>
    CryptoJS.AES.encrypt(value, CryptoJS.enc.Utf8.parse(key), {
      iv: CryptoJS.enc.Utf8.parse(iv),
      padding: CryptoJS.pad.Pkcs7,
      mode: CryptoJS.mode.CBC,
    });

  if (code == 0 && token) {
    if (!isObject(object)) {
      console.warn('参数不是对象');
      return;
    }
    if (isEmpty(object)) {
      console.warn('参数不能为空');
      return;
    }
    const result = {};
    Object.keys(object).forEach(j => {
      const value = object[j];
      result[j] = cipher(value, cryptoKey).toString();
    });

    return { ...result, token };
  }
  return { error: msg };
}
/**
 * 复制
 */
export function copy(text, then = () => {}) {
  const content = document.createElement('p');
  content.textContent = text;
  content.id = 'copytext';
  document.body.appendChild(content);
  const copyDOM = document.getElementById('copytext');

  const range = document.createRange();
  window.getSelection().removeAllRanges();
  range.selectNode(copyDOM);
  window.getSelection().addRange(range);
  const successful = document.execCommand('copy');
  if (successful) {
    then(true);
  } else {
    then(false);
  }
  window.getSelection().removeAllRanges();
  document.body.removeChild(content);
}

/**
 * 获取视频第一帧
 *  */
export const getVideoBase64 = url =>
  new Promise(resolve => {
    let dataURL = '';
    const video = document.createElement('video');
    video.setAttribute('crossOrigin', 'anonymous'); // 处理跨域
    video.setAttribute('src', url);
    video.setAttribute('width', 400);
    video.setAttribute('height', 240);
    video.addEventListener('loadeddata', () => {
      const canvas = document.createElement('canvas');
      const { width } = video; // canvas的尺寸和图片一样
      const { height } = video;
      canvas.width = width;
      canvas.height = height;
      canvas.getContext('2d').drawImage(video, 0, 0, width, height); // 绘制canvas
      dataURL = canvas.toDataURL('image/jpeg'); // 转换为base64
      resolve(dataURL);
    });
  });

/**
 *
 * params sto,zt
 * 格式化品牌
 *
 * _name 返回格式化后的名称
 */
export const brandsMap = str =>
  !str ? [] : str.split(',').map(item => brands.find(itemm => itemm.code === item));
export const brandsMap_name = (str, isShort) =>
  brandsMap(str)
    .map(item => (isShort ? item?.short_name : item?.name))
    .reduce((pre, next) => `${pre ? `${pre},` : pre}${next}`, '');

// 触发文件下载
export function triggerDownloadFile(path) {
  const a = document.createElement('a');
  a.href = path;
  a.target = '_blank';
  document.body.append(a);
  a.click();
  a.remove();
}

/**
 * form表单下载
 * @param {string} action 下载地址
 * @param {object} payload 下载参数
 *  */
export function formDownloadFile(action, payload = {}) {
  const form = document.createElement('form');
  document.body.appendChild(form);
  Object.keys(payload).forEach(item => {
    const input = document.createElement('input');
    input.type = 'hidden';
    input.name = item;
    input.value = payload[item];
    form.appendChild(input);
  });
  form.method = 'POST';
  // form.target = '_blank'
  form.action = action;
  form.submit();
  document.body.removeChild(form);
}

export const mergeObjectsByKeys = (arr, keys) => {
  const mergedMap = new Map();

  for (let i = 0; i < arr.length; i += 1) {
    const obj = arr[i];
    const keyValues = keys.map(key => obj[key]);
    const combinedKey = keyValues.join('|');

    if (mergedMap.has(combinedKey)) {
      const mergedObj = Object.assign({}, mergedMap.get(combinedKey), obj);
      mergedMap.set(combinedKey, mergedObj);
    } else {
      mergedMap.set(combinedKey, { ...obj });
    }
  }

  return Array.from(mergedMap.values());
};
